package cmm;

import clusterMessages.ClusterMessage;
import clusterMessages.ClusterMessage_TrainingMigrate;
import clusterMessages.ClusterMessage_TrainingTerminateTask;
import clusterMessages.ClusterMessage_TrainingUpdateTask;
import clusterMessages.MachineTrainingData;
import clusterMessages.TaskTrainingData;
import server.SAGenTaskContext;
import spread.SpreadGroup;


public interface IClusterManagementModule {
	
//--------------------------------------------------------------------------------------------
// Server Application Interface
//--------------------------------------------------------------------------------------------
	
	/**
	 * This method is used by the SA to inform the CMM of a new task.
	 * 
	 * @param Context - The Context of the new task
	 * @throws CMMExn_ClusterErr - Failed to send message to the Cluster
	 */
	public void AppNewTask(SAGenTaskContext Context) throws CMMExn_ClusterErr;
	
	/**
	 * This method is used by the SA to update the CMM of a context of an existing task.
	 * 
	 * @param TaskID - The Task ID
	 * @param ContextChange - Incramental change data of the task's context
	 * @throws CMMExn_TaskErr - The task does not exist in the Databases
	 * @throws CMMExn_ClusterErr - Failed to send message to the Cluster
	 */
	public void AppTaskContextUpdate(Integer TaskID, SAGenTaskContext ContextChange) throws CMMExn_TaskErr, CMMExn_ClusterErr;
	
	/**
	 * This method is used by the SA to inform the CMM that it has finished servicing 
	 * an existing task.
	 * 
	 * @param TaskID - The ID of the task to terminate
	 * @throws CMMExn_TaskErr - The task does not exist in the Databases
	 * @throws CMMExn_ClusterErr - Failed to send message to the Cluster
	 */
	public void AppTaskFinish(Integer TaskID) throws CMMExn_TaskErr, CMMExn_ClusterErr;
	
	/**
	 * This method is used by the SA to close the CMM Spread connection to the cluster,
	 * and to terminate all CMM threads.
	 * 
	 * @throws CMMExn_ClusterErr 
	 * 
	 */
	public void Close() throws CMMExn_ClusterErr;
	
//	--------------------------------------------------------------------------------------------
//	 Proxy Interface
//	--------------------------------------------------------------------------------------------	
	
	/**
	 * This method is used by the ProxyServer thread to query the least busy server 
	 * in the cluster.
	 * 
	 * @return
	 */
	public ConnectionInformation FindLeastBusyServerInfo();
	
//	--------------------------------------------------------------------------------------------	
	
	/**
	 * @param ModuleName
	 * @param Entry
	 */
	public void AddLogEntry(String ModuleName, String Entry);

//	--------------------------------------------------------------------------------------------
	
	public void FatalError();
	
//	--------------------------------------------------------------------------------------------
//	 Mentor Interface
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method allows the Mentor thread to send a training message to
	 * the Cluster.
	 * 
	 * @param Message - A {@link ClusterMessage_TrainingUpdateTask} to be sent.
	 * @throws CMMExn_ClusterErr - An error ocured while trying to send the message.
	 */
	public void SendTrainingMsg(ClusterMessage_TrainingUpdateTask Message) throws CMMExn_ClusterErr;
	
//	--------------------------------------------------------------------------------------------	

	/**
	 * This method allows the Mentor thread to send a training session 
	 * termination message to the Cluster.
	 * 
	 * @param Message - A {@link ClusterMessage_TrainingTerminateTask} to be sent.
	 * @throws CMMExn_ClusterErr - An error ocured while trying to send the message.
	 */
	public void SendTrainingMsg(ClusterMessage_TrainingTerminateTask Message) throws CMMExn_ClusterErr;
	
//	--------------------------------------------------------------------------------------------
//	 AdvancedSpreadListener Interface
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is called by the {@link AdvancedSpreadListener},
	 * whenever it recieves a message the CMM should store for later 
	 * processing, if the CMM is in Training.
	 * 
	 * @param message - The received message that should be stored 
	 */
	public void StoreMessageWhileTraining(ClusterMessage message);

//	--------------------------------------------------------------------------------------------	
	
	/**
	 * This method is called by the {@link AdvancedSpreadListener},
	 * whenever it receives a message indicating that there was a
	 * Cluster structure change resulting a machine leaving the cluster.
	 * note: this is also trigered by a spread deamon connecting to the Cluster,
	 * but in this case - nothing happens.
	 * 
	 * @param StayedMachines - An array of the machines that remain in the Cluster.
	 */
	public void HandleNetworkEvent(SpreadGroup[] StayedMachines);
	
// --- Membership Messages ---	
	/**
	 * This method is called by the membershipMessageReceived method
	 * of the {@link AdvancedSpreadListener}, when it receives a group joining message
	 * in which this local machine is the joiner, and it is the only 
	 * machine in the Cluster group. 
	 */
	public void ReceiveLocalFirstJoin();
	
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is called by the membershipMessageReceived method
	 * of the {@link AdvancedSpreadListener}, when it receives a group joining message
	 * in which the joiner is not the local machine.
	 * 
	 * @param MachineName - the Cluster name of the new joined machine 
	 */
	public void ReceiveNewMachineJoin(String MachineName);
	
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is called by the membershipMessageReceived method
	 * of the {@link AdvancedSpreadListener}, whenever it receives a group
	 * joining message in which the local machine is the joiner, and it is not
	 * the only machine in the Cluster group.
	 */
	public void ReceiveLocalClusterJoin();
	
//	--------------------------------------------------------------------------------------------	

	/**
	 * This method is called by the membershipMessageReceived method
	 * of the {@link AdvancedSpreadListener}, whenever it receives a group
	 * leave message from the Cluster.
	 * 
	 * @param LeavingMachineName - The name of the leaveing Machine
	 */
	public void ReceiveClusterLeave(String LeavingMachineName);

//	--------------------------------------------------------------------------------------------	
	
//	 --- Application Messages ---		
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Application New Task" message arives.
	 * 
	 * @param MachineID
	 * @param Context
	 */
	public void ReceiveAppNewTask(Integer MachineID, SAGenTaskContext Context);
	
//	--------------------------------------------------------------------------------------------	

	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Application Update Task" message arrives.
	 * 
	 * @param MachineID
	 * @param TaskID
	 * @param ContextUpdate
	 */
	public void ReceiveAppUpdateTask(Integer MachineID, Integer TaskID, SAGenTaskContext ContextUpdate);

//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Application Terminate Task" message arrives.
	 * 
	 * @param MachineID
	 * @param TaskID
	 */
	public void ReceiveAppTerminateTask(Integer MachineID, Integer TaskID);

//	--------------------------------------------------------------------------------------------

	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Application Migrate Task" message arrives.
	 * 
	 * @param MachineID - The new owner of the Task
	 * @param TaskID - The TaskID that is being transfered
	 */
	public void ReceiveAppMigrate(Integer MachineID, Integer TaskID);
	
//	--------------------------------------------------------------------------------------------	
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Application Transfer Task" message arrives.
	 * 
	 * @param SenderID - The MachineID of the previous owner of the Task, and the sender of the message. 
	 * @param TaskID - The TaskID that is being transfered.
	 * @param NewOwnerID - The MachineID of the new owner of the Task,
	 */
	public void ReceiveAppTransferTask(Integer SenderID, Integer TaskID, Integer NewOwnerID);
	
//	--------------------------------------------------------------------------------------------	
	
//	 --- Proxy Server Messages ---		
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Proxy New Task" message arrives.
	 * 
	 * @param MachineID
	 * @param Context
	 */
	public void ReceiveProxyNewTask(Integer MachineID, ProxyContext Context);

//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Proxy New Task" message arrives. 
	 * 
	 * @param MachineID - The new owner of the Task
	 * @param TaskID - The TaskID that is being transfered
	 */
	public void ReceiveProxyMigrate(Integer MachineID, Integer TaskID);
	
//	--------------------------------------------------------------------------------------------	
	
//	 --- Training Messages ---
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Training New Task" message arrives.
	 * 
	 * @param MachineID
	 * @param Context
	 */
	public void ReceiveTrainingNewTask(Integer MachineID, MachineTrainingData Context);
	
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Training Update Task" message arrives.
	 * 
	 * @param MachineID - The sender MachineID
	 * @param TrainingSessionID - The training session TaskID
	 * @param Data - The Trained task compacted inside a {@link TaskTrainingData} object.
	 */
	public void ReceiveTrainingUpdateTask(Integer MachineID, Integer TrainingSessionID, TaskTrainingData Data, ClusterMessage ClusterMSG);
	
//	--------------------------------------------------------------------------------------------	

	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Training Terminate Task" message arrives. 
	 * 
	 * @param MachineID - The sender MachineID
	 * @param TrainingSessionID - The training session TaskID
	 * @param TraineeName - The name of the Trainee machine.
	 */
	public void ReceiveTrainingTerminateTask(Integer MachineID, Integer TrainingSessionID, String TraineeName, ClusterMessage ClusterMSG);
	
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "Training Migrate Task" message arrives. 
	 * 
	 * @param MachineID - The new owner of the Task (The new Mentor)
	 * @param TaskID - The TaskID that is being transfered (The Training SessionID) 
	 * @param TraineeName - The name of the Trainee of the Training session
	 * @param ReceivedMSG - The received {@link ClusterMessage_TrainingMigrate} message
	 */
	public void ReceiveTrainingMigrate(Integer MachineID, Integer TaskID, String TraineeName, ClusterMessage_TrainingMigrate ReceivedMSG);
	
//	--------------------------------------------------------------------------------------------
	
//	 --- Misc. Messages ---		
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever a "New Server Ready" message arives.
	 * 
	 * @param NewMachineEntry - The {@link MachineEntry} of the new server.
	 */
	public void ReceiveNewServerReady(MachineEntry NewMachineEntry);
	
//	--------------------------------------------------------------------------------------------
	
	/**
	 * This method is used by the {@link AdvancedSpreadListener} whenever it recieves an unsupported message.
	 */
	public void ReceiveUnsupportedMessage();
	
//	--------------------------------------------------------------------------------------------
	
	
}
